#pragma once

// Copyright (c) 2010 Manuel Peinado Gallego <manuel.peinado@gmail.com>
// Distributed under the MIT license

// SelectionManager.h : interface of the SelectionManager class
//

#include "WorldFollower.h"
#include "SmartEnum.h"
#include <set>
class Selectable;
class Ui;

BEGIN_ENUM(SelectionType)
    NOTHING, BLOCK, TILE
END_ENUM(SelectionType)

class SelectionManager;

class SelectionChangeListener 
{
public:
    virtual void onSelectionChanged(SelectionManager*)  { }
};


// Cannot be UI follower because that would be a circular reference!

// We inherit WorldFollower because we want to be notified when a 
// node is removed, to change the selection in case the removed
// node is the current selection

class SelectionManager : public WorldFollower, boost::noncopyable
{
public:

    // ************************************************************************

    SelectionManager(Ui* ui);
    virtual ~SelectionManager();

    // ************************************************************************

    bool select(Selectable* node, int subSelection=-1);
    bool clearSelection(bool forceNotification=false);

    // Returns NULL if no node is selected
    Selectable* getSelection() const;

    // -1 if no sub-selection
    int getSubSelection();

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
    // Clears selection and listeners
    void clearListeners(); 

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
    // Adds/removes a new listener

    void addSelectionChangeListener(SelectionChangeListener * listener);
    void removeSelectionChangeListener(SelectionChangeListener * listener);

protected:

	void onNodeEvent(const NodeEvent&) override;

private:

    // We use set<> to avoid duplicates
    std::set<SelectionChangeListener *> m_changeListeners;
    
    void notifyChangeListeners();

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 

    Selectable* m_selection;
    int m_subSelection;

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 

    Ui* m_ui;
};

